package com.zecan.blog.utils;

import com.zecan.blog.rabbitmq.event.ChatRoomEvent;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName RedisUtils
 * @Description
 * @date 2022/10/29 11:59
 * @Version 1.0
 * redis 工具类
 */
@Component
public class RedisUtils {
    /**
     * Redis工具类
     *
     * @author Huangliniao
     * @version 1.0
     * @since 2022-05-07
     */

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 普通 string 型
     * 存放Object到指定的key
     *
     * @param key
     * @param value
     * @return
     */
    public boolean hset(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * R list 存储数据
     *
     * @param key
     * @param value
     * @return
     */
    public boolean listSet(String key, Object value, Integer time) {

        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time != -1) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 存放hash set
     *
     * @param key
     * @param key
     * @param value
     * @return
     */
    public boolean hashSet(String key, String hashKey, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, hashKey, value);
            if (time != -1) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 存放Object到指定的key，并指定时效时间
     *
     * @param key
     * @param value
     * @param time  单位为秒
     * @return
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                redisTemplate.opsForValue().set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    public boolean setIfAbsent(String key, Object value, long time) {
        try {
            if (time > 0) {
               return redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS);
            } else {
                return redisTemplate.opsForValue().setIfAbsent(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 获取指定key的值
     *
     * @param key
     * @return
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 获取指定hash key的值
     *
     * @param key
     * @return
     */
    public Object hashGet(String key, String hashKey) {
        if (key != null && hashKey != null) {
            return redisTemplate.opsForHash().get(key, hashKey);
        }
        return null;
    }

    /**
     * 在redis中获取指定key所有值
     */
    public Set<String> getKeys(String key) {
        if (key != null) {
            return redisTemplate.keys(key);
        }
        return null;
    }

    /**
     * 在redis中根据key获取
     * @return
     */
    public List<Object> multiGetStringKey(Set<String> keys) {
        if (keys != null) {
            return redisTemplate.opsForValue().multiGet(keys);
        }
        return null;
    }

    /**
     * 删除key
     *
     * @param key
     */
    @SuppressWarnings("unchecked")
    public void del(String key) {
        redisTemplate.delete(key);
    }


    /**
     * 删除hashkey
     *
     * @param key
     */
    @SuppressWarnings("unchecked")
    public void delHash(String key, String hashKey) {
        redisTemplate.opsForHash().delete(key, hashKey);
    }

    /**
     * 根据key值删除redis数据
     * @param keys
     */
    public void delKeys(Set<String> keys) {
        this.redisTemplate.delete(keys);
    }
    /**
     * 指定key的过期时间
     *
     * @param key
     * @param time 单位为秒
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获取key的过期时间，单位为秒
     *
     * @param key
     * @return 返回-1表示没有指定时效时间
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }


    /**
     * 是否存在key
     *
     * @param key
     * @return true-存在，false-不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key
     * @param delta
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }



    /**
     * 递减
     *
     * @param key
     * @param delta
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    public boolean hasHashKey(String key, String hashKey) {
        try {
            return this.redisTemplate.opsForHash().hasKey(key, hashKey);
        } catch (Exception var4) {
            var4.printStackTrace();
            return false;
        }
    }

    public long hashIncr(String key, String hashKey, long data) {
        if (data < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForHash().increment(key, hashKey, data);
    }

    /**
     * 获取当前文章有多少个点赞信息
     */
    public Long getHashKeySize(String key) {
        return redisTemplate.opsForHash().size(key);
    }


    /**
     * 获取添加在hash中的点赞信息
     * @return
     */
    public String[] getAddHashValues() {
        List<Object> values = redisTemplate.opsForHash().values(BlogConstant.USER_GOOD_ARTICLE);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < values.size(); i++) {
            // 添加每一个文章id 键值对
            sb.append(values.get(i));
            // 添加分割, 如果还存在后续的内容的话
            if (i < values.size() - 1) {
                sb.append(',');
            }
        }
        return sb.toString().split(",");
    }

    /**
     * 获取保存在redis中删除点赞的hash信息
     * @return
     */
    public String[] getDelHashValues() {
        List<Object> values = redisTemplate.opsForHash().values(BlogConstant.DEL_GOOD_ARTICLE);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < values.size(); i++) {
            sb.append(values.get(i));
            if (i < values.size() - 1) {
                sb.append(',');
            }
        }
        List<String> list = new ArrayList<>();
        list.add(sb.toString());
        String[] split = list.get(0).split(",");
        return split;
    }

    /**
     * 获取保存在redis中聊天室记录信息
     * @return
     */
    public List<ChatRoomEvent> getChatRoomEvent() {
        List<Object> chatRoomRecord = redisTemplate.opsForList().range(BlogConstant.CHAT_ROOM,0,-1);
        List<ChatRoomEvent> chatRoomEvents = new ArrayList<>();
        if(chatRoomRecord != null) {
            for (Object o : chatRoomRecord) {
                chatRoomEvents.add((ChatRoomEvent) o);
            }
        }
        // 返回对应的聊天内容
        return chatRoomEvents;
    }



}

